#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Time: 2020/3/18  15:56
# @Author: 余浪人
# @email: yulangren520@gmail.com
from ..lib.cache_sys import cache
from pathlib import Path
from . import sys_bp
from .. import get_sys_url
from ..lib.public import errors
import socket, platform, os, cymysql, redis
from cymysql.err import OperationalError
from redis.exceptions import TimeoutError
from apps.forms.install_form import Install_Form
from flask import render_template, jsonify, request, current_app, json, url_for
from apps.models.separate_model import TL_Separate_Model
from apps.models.synthesize_model import TL_Connector_Model, TL_WebApp_Model, TL_Indexes_Model, TL_ThemePush_Model
from apps.models.system_model import TL_System_Model, TL_Redis_Model, TL_PayConf_Model, TL_Email_Model, TL_Save_Model, \
    TL_MySql_Model
from apps.models.member_model import TL_Member_Model, db
from apps.lib.public import initialize, batch_add


def path_access(path):
    r = os.access(path, os.R_OK)
    w = os.access(path, os.W_OK)
    f = os.access(path, os.F_OK)
    x = os.access(path, os.X_OK)
    return r, w, f, x


def init_system(form):
    if not len(TL_System_Model.query.filter().all()):
        initialize(TL_System_Model, db, {'web_domain': form.web_domain.data})
    if not len(TL_Redis_Model.query.filter().all()):
        initialize(TL_Redis_Model, db, {'redis_host': form.redis_db_host.data, 'redis_port': form.redis_db_port.data,
                                        'redis_password': form.redis_db_password.data})
    if not len(TL_PayConf_Model.query.filter().all()):
        initialize(TL_PayConf_Model, db)
    if not len(TL_Connector_Model.query.filter().all()):
        initialize(TL_Connector_Model, db, {"status": 0})
    if not len(TL_WebApp_Model.query.filter().all()):
        initialize(TL_WebApp_Model, db, {"status": 0})
    if not len(TL_Email_Model.query.filter().all()):
        initialize(TL_Email_Model, db)
    if not len(TL_Save_Model.query.filter().all()):
        initialize(TL_Save_Model, db)
    if not len(TL_Indexes_Model.query.filter().all()):
        initialize(TL_Indexes_Model, db, {'indexes_design': f'{form.web_domain.data}/detail_page/[*tl-did*]'})
    if not len(TL_Separate_Model.query.filter().all()):
        initialize(TL_Separate_Model, db)
    if not len(TL_MySql_Model.query.filter().all()):
        initialize(TL_MySql_Model, db, {'mysql_host': form.mysql_db_host.data, 'mysql_dbName': form.mysql_db_name.data,
                                        'mysql_user': form.mysql_db_username.data,
                                        'mysql_password': form.mysql_db_password.data,
                                        'mysql_port': int(form.mysql_db_port.data)})
    if not len(TL_ThemePush_Model.query.filter().all()):
        batch_add(TL_ThemePush_Model, db,
                  [{'identifier': 'default_one', 'is_current': 1}, {'identifier': 'default_two'}])
    if not len(TL_Member_Model.query.filter().all()):
        initialize(TL_Member_Model, db,
                   {"username": form.username.data, "password": form.password.data, "remark": "超级管理员"})


@sys_bp.route('/install', endpoint='install', methods=['GET', 'POST'])
def install():
    setting = Path(os.path.join(get_sys_url(), 'apps/setting.json'))
    if setting.exists() or current_app.config.get('SQLALCHEMY_DATABASE_URI'):return '提示：系统不可重复安装哦！',200
    if request.method == 'POST':
        cache.clear()
        install = Install_Form(request.form)
        if install.validate():
            current_app.config.update({
                "SQLALCHEMY_DATABASE_URI": f"mysql+cymysql://{install.mysql_db_username.data}:{install.mysql_db_password.data}@{install.mysql_db_host.data}:{install.mysql_db_port.data}/{install.mysql_db_name.data}"
            })
            with current_app.app_context():
                db.create_all()
                f = setting.open('w', encoding='utf-8')
                f.write(json.dumps({'database': {
                    "db_host": install.mysql_db_host.data, 'db_name': install.mysql_db_name.data,
                    'db_port': install.mysql_db_port.data, 'db_user': install.mysql_db_username.data,
                    'db_pwd': install.mysql_db_password.data
                }, 'redis_db': {'db_host': install.redis_db_host.data, 'db_port': install.redis_db_port.data,
                                'db_pwd': install.redis_db_password.data}
                }))
                f.close()
                init_system(install)
            cache.clear()
            return jsonify({'status': 0, 'redirect': url_for('sys_bp.member_login')})
        return jsonify({'status': 4, 'msg': errors(install)})
    s_r, s_w, _, _ = path_access(get_sys_url())
    u_r, u_w, _, _ = path_access(os.path.join(get_sys_url(), 'apps/static/uploads'))
    i_r, i_w, _, _ = path_access(os.path.join(get_sys_url(), 'apps/templates/web_template'))
    data = {
        'system_path': get_sys_url(),
        'python_version': platform.python_version(),
        'os_version': platform.system(),
        'server_ip': socket.gethostbyname(socket.gethostname()),
        'system_access': {'r': s_r, 'w': s_w},
        'upload_access': {'r': u_r, 'w': u_w},
        'install_access': {'r': i_r, 'w': i_w},
    }
    return render_template('install_template/install_index.html', system=data)


@sys_bp.route('/db_connect/<int:classify>', endpoint='db_connect', methods=['GET'])
def db_connect(classify):
    status = True
    if classify == 1:
        config = {
            "host": request.args.get('mysql_db_host'),
            "user": request.args.get('mysql_db_username'),
            "passwd": request.args.get('mysql_db_password'),
            "db": request.args.get('mysql_db_name'),
            "port": int(request.args.get('mysql_db_port')),
            'connect_timeout': 1,
        }
        try:
            con = cymysql.Connect(**config)
            con.close()
        except OperationalError as e:
            status = False
    elif classify == 2:
        config = {
            'host': request.args.get('redis_db_host', 'localhost'),
            'port': request.args.get('redis_db_port', 6379),
            'password': request.args.get('redis_db_password', None)
        }
        try:
            r = redis.Redis(**config, socket_connect_timeout=1, db=15)
            r.set('test', '1', 1)
            r.close()
        except TimeoutError as e:
            status = False
    else:
        return jsonify({'status': 1, 'msg': '数据库参数错误'})
    if not status: return jsonify({'status': 1, 'connect': status, 'msg': '信息有误'})
    return jsonify({'status': 0, 'connect': status})
